# -*- coding: utf-8 -*-
# @Time      : 2025-08-01
# @Author    : 2023090007@ahdy.edu.cn
# @File      : init
# @Desc  
import os
import time
from datetime import datetime
from common.loghandler import logger
from business.biz_base import BizBase
from common.system import System

class BizSms(BizBase):


	task_id = 0
	last_heartbeat_time = 0

	def update_heartbeat_time(self):
		self.last_heartbeat_time = time.time()

	def __call__(self, *args, **kwargs):
	# 1. 心跳检查(更新task_id对应的任务的modify_time)

		logger.info("BizSms heartbeat start ...  ")
		# 更新task_id 对应的任务的modify_time
		update_sql = f"""UPDATE tasks SET modify_time = %s WHERE id = %s and status=1 limit 1"""
		update_data = [datetime.now(), 0]
		# 心跳间隔30s 可以设计成配置化
		while self.task_id > 0 and time.time() - self.last_heartbeat_time > 30:
			logger.info("BizSms heartbeat start ...  (task_id:%s）", self.task_id)
			# 更新modify_time字段
			update_data[0] = datetime.now()
			update_data[1] = self.task_id
			db = System.DbClient()
			affected_rows = db.execute_update(update_sql, update_data)
			logger.info("update_sql:%s, update_data:%s, affected_rows:%s", update_sql, update_data, affected_rows)
			# 更新心跳
			self.update_heartbeat_time()

			

	def exec(self, worker):

		# 1. 获取分布式锁:循环获取直到成功
		# 2. 分配任务:查询status=0任务，更新status=1,host pid 字段更新
		# 3. 释放分布式锁: 释放锁，让其他进程获取
		# 4. 执行任务: 查询分配成功的任务(staus=1 and host=? and pid = ?)
		# 5. 执行结束：status=>2
		# 6. 异常任务重置:(status=1 && now-modify_time > threshold)重置(status=>0)
		# 注意: DB需要根据实际查询建立合适索引

		logger.info("BizSms start ... (worker.pid:%s, worker.no:%s)", worker.pid, worker.no)
		lock = System.RedisLock()
		# 获取分布式锁
		while not lock.acquire():
			time.sleep(1)
		# 测试代码
		db = System.DbClient()
		select_sql = f"""SELECT * FROM tasks WHERE status = %s limit 10"""
		results = db.execute_query(select_sql, (0,))
		ids = []
		if results:
			for row in results:
				ids.append(row['id'])
			placeholders = ", ".join(["%s"] * len(ids))
			update_sql = f"""UPDATE tasks SET host = %s, pid = %s, status=1 WHERE id in ({placeholders}) and status = 0 limit 10"""
			update_data = [System.GetHostIp(), os.getpid()] + ids
			# 分配任务
			affected_rows = db.execute_update(update_sql, update_data)
			logger.info("update_sql:%s, update_data:%s, affected_rows:%s", update_sql, update_data, affected_rows)
		# 释放分布式锁
		lock.release()
			# 执行任务
		if ids:
			for task_id in ids:
				self.task_id = task_id
				time.sleep(3) # 模拟执行任务 调用下游服务发送短信
			placeholders = ", ".join(["%s"] * len(ids))
			update_sql = f"""UPDATE tasks SET host = %s, pid = %s, status=2 WHERE id in ({placeholders}) and status = 1 limit 10"""
			update_data = ['', 0] + ids
			# 任务执行成功 更新状态
			affected_rows = db.execute_update(update_sql, update_data)
			logger.info("update_sql:%s, update_data:%s, affected_rows:%s", update_sql, update_data, affected_rows)
		# 异常任务重置(status=1 and now-modify_time > 60)
		select_sql = f"""SELECT id FROM tasks WHERE modify_time < NOW() - INTERVAL %s SECOND and status=1 and pid !=0 limit 10"""
		results = db.execute_query(select_sql, (60,))
		if results:
			for row in results:
				ids.append(row['id'])
			placeholders = ", ".join(["%s"] * len(ids))
			update_sql = f"""UPDATE tasks SET host = %s, pid = %s, status=0 WHERE id in ({placeholders}) and status = 0 limit 10"""
			update_data = ['', 0] + ids
			# 异常任务重置
			affected_rows = db.execute_update(update_sql, update_data)
			logger.info("update_sql:%s, update_data:%s, affected_rows:%s", update_sql, update_data, affected_rows)
		# 本次任务执行完成 退出worker ，Master重启创建worker执行 ，防止worker长期运行导致的内存泄露问题
		# 可以设计worker执行多次再退出 根据业务情况设计
